#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/mm.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/module.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/input.h>
#include "linux/workqueue.h"

/*
note: four key, use for input system.
	EINT0	-->	GPF0
	EINT2	-->	GPF2
	EINT11	-->	GPG3
	EINT19	--> GPG11
*/

struct input_dev *devp;

typedef struct key_irq_desc{
	int irq;
	int pin;
	int pin_val;
	char *name;
	irqreturn_t (*irq_func)(int irq, void *dev_id);
}KEY_DESC;

static struct work_struct eint0_wq, eint1_wq;


static void eint0_func(struct work_struct *work)
{
	printk("eint0_func\n");
}

static void eint1_func(struct work_struct *work)
{
	printk("eint1_func\n");
}


static irqreturn_t eint0_irq_hdl(int irq, void *dev_id)
{
	printk("Eint 0 ...\n");

	schedule_work(&eint0_wq);

	return IRQ_RETVAL(IRQ_HANDLED);
}

static irqreturn_t eint2_irq_hdl(int irq, void *dev_id)
{
	printk("Eint 2 ...\n");

	schedule_work(&eint1_wq);

	return IRQ_RETVAL(IRQ_HANDLED);
}


static KEY_DESC key_irq_table[]={
	{IRQ_EINT0, S3C2410_GPF(0), S3C2410_GPF0_EINT0,  "eint_0", eint0_irq_hdl},
	{IRQ_EINT2, S3C2410_GPF(2), S3C2410_GPF2_EINT2,  "eint_2", eint2_irq_hdl},
};

  
static int  __init input_key_init(void)
{
	int i, ret;


	for(i=0; i<(sizeof(key_irq_table)/sizeof(key_irq_table[0])); i++){
		ret = request_irq(key_irq_table[i].irq, key_irq_table[i].irq_func, 
			IRQ_TYPE_EDGE_FALLING, key_irq_table[i].name, (void *)&key_irq_table[i]);
	}
	
	INIT_WORK(&eint0_wq, eint0_func);
	INIT_WORK(&eint1_wq, eint1_func);

	return 0;
}

static void  __exit input_key_exit(void)
{
	int nr;

	for(nr=0; nr<(sizeof(key_irq_table)/sizeof(key_irq_table[0])); nr++){
		free_irq(key_irq_table[nr].irq, (void *)&key_irq_table[nr]);
	}
	
	
}

module_init(input_key_init);
moudle_exit(input_key_exit);


MODULE_LICENSE("GPL");

